package com.example.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.dto.UserLoginDTO;
import com.example.entity.Admin;
import com.example.entity.User;
import com.example.entity.User;
import com.example.handlers.BaseContext;
import com.example.mapper.UserMapper;
import com.example.service.AdminService;
import com.example.service.UserService;
import com.example.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.utils.JwtUtil;
import com.example.vo.UserLoginVO;
import com.example.vo.UserLoginVO;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author wuyunbin
 * @since 2025-03-30
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Lazy
    @Resource
    private AdminService adminService;

    @Resource
    private JwtUtil jwtUtil;

    @Override
    public void saveUser(User user) {
        // 验证手机号格式
        if (!user.getUsername().matches("^1[3-9]\\d{9}$")) {
            throw new RuntimeException("手机号格式不正确");
        }

        // 密码加密处理
        String encryptedPwd = BCrypt.hashpw(user.getPassword(), BCrypt.gensalt());
        log.info("原始密码：{} | 加密后的密文：{}", user.getPassword(), encryptedPwd);

        Admin admin = new Admin();
        BeanUtil.copyProperties(user, admin);
        admin.setPassword(encryptedPwd);  // 关键：使用加密后的密码
        adminService.save(admin);

        LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Admin::getUsername, user.getUsername());
        admin = adminService.getOne(wrapper);

        user.setAdminId(admin.getId());
        user.setAvatar("https://tse2-mm.cn.bing.net/th/id/OIP-C.p6hdmBEvZCMwVcWDVnQr0QAAAA?w=164&h=180&c=7&r=0&o=5&dpr=1.5&pid=1.7");
        user.setNickname("用户_"+admin.getId());
        user.setIntroduction("一枚程序员");

        user.setPassword(encryptedPwd);
        this.save(user);


    }

    @Override
    public UserLoginVO login(UserLoginDTO userLoginDTO) {
        // 条件构造器，用来构建查询条件
        LambdaQueryWrapper<User> Wrapper = new LambdaQueryWrapper<>();
        // 设置查询条件，要求数据库里的username与前端传进来的username相等
        Wrapper.eq(User::getUsername, userLoginDTO.getUsername());
        // 调用getOne()方法，根据条件构造器查询数据库，返回User对象
        User user = this.getOne(Wrapper);

        // 如果没有对应的user对象，则抛出异常
        // 抛出异常可以立即停止当前的执行流程
        if (user == null){
            throw new RuntimeException("用户名不存在或者密码不正确");
        }
        // 使用BCrypt算法的checkpw()方法对用户输入的密码和数据库里密码的哈希值进行匹配
        if(!BCrypt.checkpw(userLoginDTO.getPassword(), user.getPassword())){
            throw new RuntimeException("用户名不存在或者密码不正确");
        }

        // Claims是一个Map集合（双列集合 Key,Value）
        // JWT（JSON Web Token)
        // Jwts.claims()：创建一个新的 Claims 对象，该对象可以用来设置JWT中的声明信息。
        Claims claims= Jwts.claims();
        // 将user的id存放在claims中
        claims.put("id",user.getId());
        //todo 秘钥是写死的，需要活的密钥
//        Key key= Keys.hmacShaKeyFor("12345689012345678901234567890123456890123456789012345678901234568901234567890123456789012345689012345678901234567890".getBytes(StandardCharsets.UTF_8));
        // 使用claims创建token
        String token=jwtUtil.createToken(claims);

        // 创建UserLoginVO对象，将token存入，后端传递给前端
        UserLoginVO userLoginVO = new UserLoginVO();
        userLoginVO.setToken(token);
        return userLoginVO;
    }
}
